package com.zhongan.gateway.service.impl;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import redis.clients.jedis.Jedis;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.zhongan.gateway.bean.Api;
import com.zhongan.gateway.bean.ApiAttribute;
import com.zhongan.gateway.bean.ApiGroup;
import com.zhongan.gateway.common.constant.GwDeveloperApiConstant;
import com.zhongan.gateway.mapper.ApiAttributeMapper;
import com.zhongan.gateway.mapper.ApiGroupMapper;
import com.zhongan.gateway.mapper.ApiMapper;
import com.zhongan.gateway.service.ApiService;
import com.zhongan.gateway.service.RedisService;
import com.zhongan.gateway.web.common.PageDTO;

@Component
public class ApiServiceImpl implements ApiService {

    private static final Logger logger = LoggerFactory.getLogger(ApiServiceImpl.class);
    @Resource
    private ApiGroupMapper      apiGroupMapper;

    @Resource
    private ApiMapper           apiMapper;

    @Resource
    private ApiAttributeMapper  apiAttributeMapper;
    @Resource
    private RedisService        redisService;

    @Override
    public int deleteApi(Api record) {
        String key = GwDeveloperApiConstant.GW_CACHE_API + record.getServiceName() + "_" + record.getVersion();
        redisService.clearCacheByKey(key);
        logger.info("start deleteApi,id={}", record.getId());
        int i = apiMapper.deleteByPrimaryKey(record.getId());
        logger.info("end deleteApi,i={}", i);

        return i;
    }

    @Override
    public Long insertApi(Api record) {
        logger.info("start insertApi, {}", record.toString());
        apiMapper.insert(record);
        logger.info("end insertApi,id={}", record.getId());

        return record.getId();
    }

    @Override
    public Api selectApiById(Long id) {
        Api api = apiMapper.selectByPrimaryKey(id);
        return api;
    }

    @Override
    public Api selectApi(String serviceName, String version) {
        Api api = null;
        String key = GwDeveloperApiConstant.GW_CACHE_API + serviceName + "_" + version;
        Jedis jedis = redisService.getJedis();
        String result = redisService.get(jedis, key);

        if (!StringUtils.isEmpty(result)) {
            api = JSONObject.parseObject(result, Api.class);
        } else {
            Api param = new Api();
            param.setServiceName(serviceName);
            param.setVersion(version);
            List<Api> apis = selectApis(param);
            if (apis != null && apis.size() != 1) {
                logger.warn("未查询到有效的api,serviceName={},version={},result size={}", serviceName, version, apis.size());
            } else {
                api = apis.get(0);
                redisService.set(jedis, key, JSONObject.toJSONString(api));
            }

        }
        redisService.closeJedis(jedis);
        return api;
    }

    @Override
    public int updateApi(Api record) {
        String key = GwDeveloperApiConstant.GW_CACHE_API + record.getServiceName() + "_" + record.getVersion();
        redisService.clearCacheByKey(key);
        logger.info("start updateApi, {}", record.toString());
        int i = apiMapper.updateByPrimaryKey(record);
        logger.info("end updateApi,i={}", i);

        return i;
    }

    @Override
    public int deleteGroupById(Long id) {
        logger.info("start deleteGroupById,id= {}", id);
        int i = apiGroupMapper.deleteByPrimaryKey(id);
        logger.info("end deleteGroupById,i={}", i);

        return i;
    }

    @Override
    public int insertApiGroup(ApiGroup record) {
        logger.info("start insertApiGroup, {}", record.toString());
        int i = apiGroupMapper.insert(record);
        logger.info("end insertApiGroup,i={}", i);

        return i;
    }

    @Override
    public ApiGroup selectGroupById(Long id) {
        ApiGroup apiGroup = apiGroupMapper.selectByPrimaryKey(id);
        return apiGroup;
    }

    @Override
    public List<ApiGroup> selectGroups() {
        ApiGroup api = new ApiGroup();
        List<ApiGroup> apiGroups = apiGroupMapper.selectByParams(api);
        return apiGroups;
    }

    @Override
    public List<ApiGroup> selectGroupsByName(String name) {
        ApiGroup api = new ApiGroup();
        api.setName(name);
        List<ApiGroup> apiGroups = apiGroupMapper.selectByParams(api);
        return apiGroups;
    }

    @Override
    public int updateApiGroup(ApiGroup record) {
        logger.info("start updateApiGroup, {}", record.toString());
        int i = apiGroupMapper.updateByPrimaryKey(record);
        logger.info("end updateApiGroup,i={}", i);

        return i;
    }

    @Override
    public List<Api> selectApis(Api record) {
        List<Api> apis = apiMapper.selectByParams(record);
        return apis;
    }

    @Override
    public PageDTO<Api> selectPageApis(String serviceName, Long groupId, Integer start, Integer limit) {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("serviceName", serviceName);
        map.put("groupId", groupId);
        int count = apiMapper.countByParams(map);
        map.put("start", start);
        map.put("limit", limit);
        List<Api> apis = apiMapper.selectPageByParams(map);
        PageDTO<Api> page = new PageDTO<Api>();
        page.setStart(start);
        page.setLimit(limit);
        page.setRows(apis);
        page.setResults(count);
        page.setHasError(false);
        return page;
    }

    @Override
    public int deleteApiAttr(Long id, Long apiId) {
        String key = GwDeveloperApiConstant.GW_CACHE_ATTR + apiId;
        redisService.clearCacheByKey(key);
        logger.info("start deleteApiAttr, id={},apiId={}", id, apiId);
        int i = apiAttributeMapper.deleteByPrimaryKey(id);
        logger.info("end deleteApiAttr,i={}", i);

        return i;
    }

    @Override
    public int insertApiAttr(ApiAttribute record) {
        String key = GwDeveloperApiConstant.GW_CACHE_ATTR + record.getApiId();
        redisService.clearCacheByKey(key);
        logger.info("start insertApiAttr, {}", record.toString());
        int i = apiAttributeMapper.insert(record);
        logger.info("end insertApiAttr,i={}", i);

        return i;
    }

    @Override
    public ApiAttribute selectApiAttrById(Long id) {
        ApiAttribute attr = apiAttributeMapper.selectByPrimaryKey(id);
        return attr;
    }

    @Override
    public List<ApiAttribute> selectApiAttrs(Long apiId) {

        String key = GwDeveloperApiConstant.GW_CACHE_ATTR + apiId;
        Jedis jedis = redisService.getJedis();
        String result = redisService.get(jedis, key);
        List<ApiAttribute> list = null;
        if (!StringUtils.isEmpty(result)) {
            list = (List<ApiAttribute>) JSONObject.parseObject(result, new TypeReference<List<ApiAttribute>>() {
            });
        } else {
            list = apiAttributeMapper.selectByApiId(apiId);
            if (null != list && !list.isEmpty()) {
                redisService.set(jedis, key, JSONObject.toJSONString(list));
            }

        }
        redisService.closeJedis(jedis);
        return list;
    }

    @Override
    public int updateApiAttr(ApiAttribute record) {
        String key = GwDeveloperApiConstant.GW_CACHE_ATTR + record.getApiId();
        redisService.clearCacheByKey(key);

        logger.info("start updateApiAttr, {}", record.toString());
        int i = apiAttributeMapper.updateByPrimaryKey(record);
        logger.info("end updateApiAttr,i={}", i);

        return i;
    }

}
